function ReadDeploymentParameters
{
  param( $file )

  [xml]$DeploymentParameters = get-content $file

  $result = @{}

  foreach ($variable in $DeploymentParameters.variables.variable)
{
    $result[$variable.name] = $variable.value
  }

  $result

  #  $assignment = '$' + 'SCRIPT:' + $executioncontext.InvokeCommand.ExpandString($variableExpr)

}

function Depricated-Reader
{
  param( $file )

  [void] [Reflection.Assembly]::LoadFile($PbndCommandsFile)

  $reader = new-object "PbndCommands.ReadXmlConfig" $ExecutionContext

  $config = $reader.readfile($file)

  $flattenArrays = new-object "PbndCommands.FlattenArrays" $config

  $flattenArrays.Process("environments")
  $flattenArrays.Process("environment\servers")
  $flattenArrays.Process("ReleaseManagement\NotificationGroups")
  $flattenArrays.Process("ReleaseManagement\emailTemplates")
  $flattenArrays.Process("ReleaseManagement\targetenvironments")
  $flattenArrays.Process("applications")
  $flattenArrays.Process("customApplication\targetenvironments")
  $flattenArrays.Process("application\targetenvironments")
  $flattenArrays.Process("application\targetenvironments\targetservers")
  $flattenArrays.Process("application\targetenvironments\envfiles")

  $flattenArrays.Root
}

function ReadDeploymentConfig
{
  param( $file )

  $AllEnv = @()
  [xml]$config = Get-Content $file

  if ($config.deployment.version -ne "1.1")
{
    Log-Message $MajorLine
    Log-Message "!!! This version of the DeploymentEnv.xml is Deprecated !!! " -foregroundcolor yellow
    Log-Message "Services and website are now stopped at the begining of the deployment and started at the end."
    Log-Message $MinorLine
    Log-Message "Message for PBND team - - all other users can ignore this section"
    Log-Message $MinorLine
    Log-Message "Update the DeploymentEnv.xml to include the version parameter at the root node."
    Log-Message "<deployment version="1.1">"
    Log-Message $MinorLine
    Log-Message "This deployment now supports cluster managed services"
    Log-Message "If this new feature is required replace the services node at"
    Log-Message "Deployment.Applications.Application.TargetEnvironments.TargetEnvironment.services"
    Log-Message "with <clusterServices name="" domain="" winService=""/>"
    Log-Message "and populate the properties accordingly." 

  }
  foreach ($environment in $config.deployment.environments.environment) 
{
    $env = @{Name = $environment.name; 
      preDeployment = $environment.preDeployment;
      postDeployment = $environment.postDeployment;
      IISReset = $environment.IISReset;
			OnTimeEnvCode = $environment.OnTimeEnvCode;
      Servers = @()
    }

    foreach ($server in $environment.servers.server) 
{
      if( ! ( $server.name -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" ) -and 
      ( $server.domain -ne $null ) -and 
      ( $server.domain -ne "" ) 
      )
{
        $FQName = "$($server.name).$($server.domain)"
      }
      else
{
        $FQName = $server.name
      } 
      $env.Servers += 
      @{Name=$server.name; 
        FQName=$FQName;
        Domain=$server.domain; 
        Volume=$server.volume; 
        Applications=@() 
      } 
    }
    $AllEnv += $env
  }

  foreach ($application in $config.deployment.applications.application) 
{
    if ($application -ne $null)
{
      $app = @{Name = $application.name; 
        Root = $application.files.root;
        delete = $application.delete;
        DestFolder=$application.DestFolder; 
        WebSite=$application.WebSite; 
        WinService=$application.WinService;
        EnvFiles = @()
        EnvCustoms = @()
        EnvServices = @()
      }
      $filesElement = $application.files
			$DeleteExcludes = $application.DeleteExcludes
      $rootPath = $executioncontext.InvokeCommand.ExpandString( $filesElement.root )
      $app.files = get-ChildItem $rootPath -recurse | where-object { $_ -is [System.IO.FileInfo] }

      foreach ($exclude in $filesElement.excludes.exclude)
			{
        $app.files = $app.files | where-object {$_.Name -notlike $exclude.pattern }
      }
			foreach ($pattern in $DeleteExcludes.Files.file)
			{
			  [array]$excludeFiles += $pattern.pattern
			}
			$app.excludeFiles += $excludeFiles
			
			foreach ($RegexPattern in $DeleteExcludes.Folders.folder)
			{
			  [array]$excludeFolders += $RegexPattern.regexPattern
			}
			$app.excludeFolders +=$excludeFolders
      foreach ($targetenvironment in $application.targetenvironments.targetenvironment)
			{
    		if (($targetenvironment.Destfolder -ne $null) -and ($TargetEnv -eq $targetenvironment.name))
				{
					$app.DestFolder = $targetenvironment.Destfolder
				}
        foreach ($envfile in $targetenvironment.envfiles.envfile)
				{
          $app.EnvFiles += 
          @{Env=$targetenvironment.name
            SrcFile=Get-ChildItem $envfile.src
            #Application Relative Destination
            Dest=$envfile.dest
            #Volume Relateive Destination 
            RelativeDest=$envfile.RelativeDest
          }
        }
        if ( $targetenvironment.envCustoms -ne $null)
				{
          foreach ($envCustom in $targetenvironment.envCustoms.envCustom)
					{
            $app.EnvCustoms += 
            @{Env=$targetenvironment.name
              SrcFile = [object[]] (Get-ChildItem $envCustom.src)
              #Implicit Destination
              ImplicitDest=$envCustom.ImplicitDest 
            }
          }
        }
        if ( $targetenvironment.services -ne $null -or $targetenvironment.clusterservices -ne $null )
{
          $app.EnvServices += 
          @{Env=$targetenvironment.name
            WebSite = $targetenvironment.services.website
            WinService = $targetenvironment.services.WinService
            AppPool = $targetenvironment.services.AppPool
            ClusterName = $targetenvironment.clusterServices.name;
            ClusterFQName = $ClusterFQName;
            ClusterWinService = $targetenvironment.clusterServices.winService;
          } 
        }
        $env = Get-Env $targetenvironment.name
        foreach ($targetserver in $targetenvironment.targetservers.targetserver) 
{
          Set-ServerApplication $env $targetserver.name $app
        }
      }
    }
  }

  foreach ($customApplication in $config.deployment.applications.customApplication) 
  {
    if ($customApplication -ne $null)
    {
      $custApp = @{}
      $custApp.Name = $customApplication.name
      $custApp.environments = @{}

      foreach ($targetenvironment in $customApplication.targetenvironments.targetenvironment)
      {
        $env = @{}
        $env.name = $targetenvironment.name
        $props = $targetenvironment | get-member | ?{$_.MemberType -eq "Property" -and $_.Name -ne "xsd" -and $_.Name -ne "xsi" -and $_.Name -ne "name"}
        if ($props -ne $null -or $props.count -gt 0)
        {
          foreach ($prop in $props)
          {
            $expr = '$targetenvironment."' + $prop.name + '"'
            $value = Invoke-Expression $expr
            $env[$prop.name] = $value
          }
        }
        $custApp.environments[$targetenvironment.name] = $env
      }
      $Global:custApps += $custApp
    }
  }
  
  if ($config.deployment.applications.databaseDeployments -ne $null)
  {
    foreach ($databaseDeployment in $config.deployment.applications.databaseDeployments.databaseDeployment) 
    {
      if ($databaseDeployment -ne $null)
      {
        $dbDeployment = @{}
        $dbDeployment.Name = $databaseDeployment.name
        $dbDeployment.config = $databaseDeployment.config
        $dbDeployment.environments = @{}
    
        foreach ($targetenvironment in $databaseDeployment.targetenvironment)
        {
          if ($targetenvironment -ne $null)
          {
            $env = @{}
            $env.name = $targetenvironment.name
            $dbDeployment.environments[$targetenvironment.name] = $env
          }
        }
        $Global:dbDeployments += $dbDeployment
      }
    }
  }
  
  $AllEnv
}
#############################################################################

function Collect-Services
{
  [xml]$config = Get-Content "./Install/DeploymentEnv.xml"

  $all = @()
  foreach ($app in $config.deployment.applications.application)
  {
    $application = @{name = $app.name;
      WinService = $app.WinService;
      WebSite = $app.website;
      AppPool = $app.AppPool;
      envServers = @();
    }

    foreach ($targetenv in $app.targetenvironments.targetenvironment)
    {

      if ($targetenv.name -eq $Env.Name )
      {
        ## FQDN check for cluster service management server  
        if ($targetenv.clusterServices -ne $null)
        {
          if( ! ( $targetenv.clusterServices.name -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" ) -and 
          ( $targetenv.clusterServices.domain -ne $null ) -and 
          ( $targetenv.clusterServices.domain -ne "" )
          )
          {
            $ClusterFQName = "$($targetenv.clusterServices.name).$($targetenv.clusterServices.domain)"
          }
          else
          {
            $ClusterFQName = $targetenv.clusterServices.name
          } 
        }
        ## start fqdn check targetenv.targetservers
        foreach ($server in $targetenv.targetservers.targetserver)
        {
          if( ! ( $server.name -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" ) -and 
              ( $server.domain -ne $null ) -and 
              ( $server.domain -ne "" )
            )
          {
            $FQName = "$($server.name).$($server.domain)"
          }
          else
          {
            $FQName = $server.name
          } 
          
          $envServers = @{App = $app.name;
            Env = $targetenv.name;
            Name = $server.name;
            FQName = $FQName;
            WebSite = $targetenv.services.website;
            WinService = $targetenv.services.winService;
            AppPool = $targetenv.services.AppPool;
            ClusterName = $targetenv.clusterServices.name;
            ClusterFQName = $ClusterFQName;
            ClusterWinService = $targetenv.clusterServices.winService;
          }
          $application.envServers += $envServers 
        } 
      }
    }
    $all += $application
  }
  return $all
}
